package de.hauck.rtmidlet.views;

import java.util.Calendar;
import java.util.Vector;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import de.hauck.rtmidlet.DownloadImageThread;
import de.hauck.rtmidlet.RTMidlet;
import de.hauck.rtmidlet.model.Configuration;
import de.hauck.rtmidlet.model.StockBean;
import de.hauck.rtmidlet.model.StockStore;
import de.hauck.rtmidlet.utils.Utils;

public class CanvasCharts extends CanvasSuper implements CommandListener,
		iCanvas {
	private Display _display;
	private Displayable _dble;
	private Font f;
	private Image[][] imageArray;
	private Image[][] imageArrayOverview;
	private String[][] downloadTime;
	private boolean[][] _isDownloading;
	private Vector _stocksVec;
	private boolean isOverview = true;
	private boolean showMenu = false;
	private int menuIndex = 0;

	private int slideNr = 1;
	private int maxSlides = 1;

	private int startNr = 0;
	private int stocksOnScreen = 6;
	private int endNr = startNr + stocksOnScreen;
	private int selectedChart = 0;
	private StockBean stock;
	private String stockName;
	private int _type;
	private String url = "";
	private int timeIndex = 0;
	private String[] timeArray;
	private PopupMenu pMenu;
	private String[] menu;
	private StockStore _myStockStore;

	public CanvasCharts(int type, Display display, Displayable dble,
			Vector stocksVec, StockStore mystore) {
		super();
		_display = display;
		_dble = dble;
		_stocksVec = stocksVec;
		_myStockStore = mystore;
		_type = type;
		menu = Configuration.getAvailableChartTypes();
		imageArray = new Image[menu.length][stocksVec.size()];
		imageArrayOverview = new Image[menu.length][stocksVec.size()];
		downloadTime = new String[menu.length][stocksVec.size()];
		_isDownloading = new boolean[menu.length][stocksVec.size()];
		calculateScreenSettings();
		f = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN,
				Font.SIZE_SMALL);
		timeArray = Configuration.getTimeIntervalls(type);
	}

	protected void paint(Graphics g) {
		pMenu = new PopupMenu(g, Font.getFont(Font.FACE_MONOSPACE,
				Font.STYLE_PLAIN, Font.SIZE_SMALL), getWidth(), getHeight(),
				menu);
		g.setFont(f);
		if (isOverview) {
			// clear screen
			g.setColor(0, 0, 0);
			g.fillRect(0, 0, getWidth(), getHeight());
			int x_cols = 0;
			int y_row = 10;
			startNr = slideNr * stocksOnScreen - stocksOnScreen;
			endNr = Math.min(startNr + stocksOnScreen, _stocksVec.size());
			for (int i = startNr; i < endNr; i++) {
				stock = (StockBean) _stocksVec.elementAt(i);
				stockName = stock.getName();
				if (stockName.length() > 10)
					stockName = stockName.substring(0, 9) + ".";

				// show overviews
				if (imageArrayOverview[_type][i] != null) {
						g.drawImage(imageArrayOverview[_type][i], x_cols + 60, y_row,
								Graphics.TOP | Graphics.HCENTER);
						g.setColor(0, 0, 0);
						g.drawString("" + stockName, x_cols + 60, y_row,
								Graphics.TOP | Graphics.HCENTER);
				} else {
					g.setColor(255, 255, 255);
					g.drawString("" + stockName, x_cols + 60, y_row,
							Graphics.TOP | Graphics.HCENTER);
					g.drawString("unavailable", x_cols + 60, y_row + 15,
							Graphics.TOP | Graphics.HCENTER);
				}
				if (selectedChart == i) {
					g.setColor(255, 0, 0);
					g.drawRoundRect(x_cols + 8, y_row - 2, 102, 82, 10, 10);
				}

				if (x_cols == 120)
					y_row += 90;
				x_cols = (x_cols + 120) % 240;
			}
			g.setColor(255, 255, 255);
			if (maxSlides > 1) {		
				g.drawString(slideNr + "/" + maxSlides, getWidth(),
						getHeight(), Graphics.BOTTOM | Graphics.RIGHT);
			}
			g.drawString(""+menu[menuIndex],0,getHeight(),Graphics.BOTTOM | Graphics.LEFT);

		} else {
			// draw chart & text
			super.paint(g);
			if (imageArray[_type][selectedChart] != null) {
				g.drawImage(imageArray[_type][selectedChart], getWidth() / 2,
						getHeight() / 2, Graphics.VCENTER | Graphics.HCENTER);
				// if image<screensize, set white color
				if (imageArray[_type][selectedChart].getHeight() < getHeight())
					g.setColor(255, 255, 255);
				else
					g.setColor(0, 0, 0);
				g.drawString(downloadTime[_type][selectedChart], getWidth(),
						getHeight(), Graphics.BOTTOM | Graphics.RIGHT);

			}

			if (_isDownloading[_type][selectedChart]) {
				paintDownloadStatus(g,f);
			}
			
			g
					.drawString(((StockBean) _stocksVec
							.elementAt(selectedChart)).getName()+" (T:"+timeIndex+")", 0,
							getHeight(), Graphics.BOTTOM | Graphics.LEFT);

		}
		if (showMenu) {
			pMenu.showMenu((byte) menuIndex, (byte) 0);
		}
	}

	public void commandAction(Command arg0, Displayable arg1) {

	}

	protected void keyPressed(int keyCode) {
		int action = getGameAction(keyCode);
		if (keyCode == KEY_NUM1) {
			// 1 = update data
			downloadImage();
			this.repaint();
		} else if (keyCode == -6 || keyCode == -7) {
			// exit
			_display.setCurrent(_dble);
		} else if (keyCode == KEY_POUND) {
			// # = toggles to overview-screen
			isOverview = !isOverview;
			this.repaint();
		} else if (keyCode == KEY_NUM3) {
			// scroll page up
			if (isOverview) {
				// selected = 0;
				// get previous slide
				if (slideNr > 1) {
					slideNr--;
					selectedChart -= stocksOnScreen;
				}
			}
			System.out.println("SlideNr: " + slideNr + ", selected: "
					+ selectedChart);
			this.repaint();
		} else if (keyCode == KEY_NUM4) {
			if (!isOverview && null!=timeArray) {
				System.out.println("decrease time intervall");
				if (timeIndex > 0)
					timeIndex--;
				else 
					timeIndex = timeArray.length - 1;
				downloadImage();
				this.repaint();
			}
		} else if (keyCode == KEY_NUM6) {
			if (!isOverview && null!=timeArray) {
				System.out.println("increase time intervall");
				if (timeIndex < timeArray.length - 1)
					timeIndex++;
				else
					timeIndex = 0;
				downloadImage();
				this.repaint();
			}
		} else if (keyCode == KEY_NUM8) {
			if (!isOverview) {
				try {
					System.out.println("scale to fullsize");
					imageArray[_type][selectedChart] = Utils.rescaleImage(imageArray[_type][selectedChart], getWidth(), getHeight());
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
				this.repaint();	
		} else if (keyCode == KEY_NUM9) {
			if (!isOverview) {
				Image img = imageArray[_type][selectedChart];
				try {
					System.out.println("rotate by 90");
					imageArray[_type][selectedChart] = Utils.rotateImage(img, 90);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {
				// 9 = scroll page down
				// get next slide
				if (slideNr < maxSlides) {
					slideNr++;
					selectedChart += stocksOnScreen;
					if (selectedChart >= _stocksVec.size() - 1)
						selectedChart = _stocksVec.size() - 1;
				}

				System.out.println("SlideNr: " + slideNr + ", selected: "
					+ selectedChart);
			}
			this.repaint();
		} else if (keyCode == KEY_NUM0) {
			// 0 = toggle menu
			if (isOverview)
				showMenu = !showMenu;
			repaint();
		} else if (keyCode == KEY_STAR) {
			String[][] strings = {{"4/6","de-/increase time"},{"8","fullscreen"},{"9","rotate"},{"0","select chart type"},{"#","toggle overview"}};
			CanvasInfo debugCanvas = new CanvasInfo(this,"Info", strings);
			RTMidlet.getInstance().show(debugCanvas);
		} else if (action == UP) {
			if (isOverview && !showMenu) {
				selectedChart -= 2;
				if (selectedChart < 0) {
					selectedChart += 2;
				}
				if (selectedChart < startNr && slideNr > 1) {
					slideNr--;
				}
			} else if (showMenu) {
				if (menuIndex > 0)
					menuIndex--;
				else
					menuIndex = menu.length - 1;
				System.out.println(menuIndex);
				repaint();
			} else {
				// get previous chart
				selectedChart--;
				if (selectedChart < 0)
					selectedChart = _stocksVec.size() - 1;
				if (imageArray[_type][selectedChart] == null
						&& !_isDownloading[_type][selectedChart])
					downloadImage();
			}
			this.repaint();
		} else if (action == DOWN) {
			if (isOverview && !showMenu) {
				System.out.println("startnr: " + startNr + " endnr: " + endNr
						+ ", size: " + _stocksVec.size());
				selectedChart += 2;

				if (selectedChart >= endNr && slideNr < maxSlides) {
					slideNr++;
				}
				if (selectedChart >= _stocksVec.size() - 1)
					selectedChart = _stocksVec.size() - 1;

			} else if (showMenu) {
				menuIndex = (menuIndex + 1) % menu.length;
				System.out.println(menuIndex);
				repaint();
			} else {
				// get next chart
				selectedChart++;
				if (selectedChart >= _stocksVec.size())
					selectedChart = 0;
				if (imageArray[_type][selectedChart] == null
						&& !_isDownloading[_type][selectedChart])
					downloadImage();
			}
			this.repaint();
		} else if (action == LEFT) {
			if (isOverview) {
				selectedChart--;
				if (selectedChart < startNr && slideNr > 1) {
					slideNr--;
				}
				if (selectedChart < 0) {
					selectedChart = _stocksVec.size() - 1;
					slideNr = maxSlides;
				}
				this.repaint();
			}
		} else if (action == RIGHT) {
			if (isOverview) {
				selectedChart++;
				if (selectedChart >= endNr && slideNr < maxSlides) {
					slideNr++;
				}
				if (selectedChart == _stocksVec.size()) {
					slideNr = 1;
					selectedChart = 0;
				}
				this.repaint();
			}
		} else if (action == FIRE) {
			if (showMenu) {
				_stocksVec = _myStockStore.getFilteredStockVector(menuIndex);
				_type = menuIndex;
				System.out.println("_type: " + _type);
				calculateScreenSettings();
				showMenu = false;
				imageArray = new Image[menu.length][_stocksVec.size()];
				imageArrayOverview = new Image[menu.length][_stocksVec.size()];
				_isDownloading = new boolean[menu.length][_stocksVec.size()];
				downloadTime = new String[menu.length][_stocksVec.size()];
				timeArray = Configuration.getTimeIntervalls(_type);
				timeIndex=0;
			} else {
				isOverview = !isOverview;
				if (!isOverview && imageArray[_type][selectedChart] == null) {
					downloadImage();
					
				}
			}
			this.repaint();

		} else {
			System.out.println("key: " + keyCode);
			this.repaint();
		}
	}

	public void showPic(Image image, int _type, int index) {
		try {
			imageArrayOverview[_type][index]=Utils.rescaleImage(
					image, 100, 80);
			if (image.getWidth()>image.getHeight())
				imageArray[_type][index] = Utils.rotateImage(image, 90);
			else
				imageArray[_type][index] = image;
			downloadTime[_type][index] = Utils.convertCal2Time(Calendar.getInstance(),
					true);
			_isDownloading[_type][index] = false;
			repaint();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void downloadImage() {
		String chartName = "";
		System.out.println("_type: " + _type);
		chartName = ((StockBean) _stocksVec.elementAt(selectedChart))
		.getChartSymbol(_type);
		url = Configuration.getURL(_type,chartName);
		System.out.println(timeIndex + " " + url);
		if (null!=timeArray && timeArray.length>timeIndex)
			url = Utils.replace(url, "<?time>", timeArray[timeIndex]);
		if (chartName != null && !chartName.equals("")) {
			_isDownloading[_type][selectedChart] = true;
			new DownloadImageThread(url, _type, selectedChart, this);
		} else {
			RTMidlet.getInstance().setCurrent(this);
			isOverview = true;
			RTMidlet.getInstance().alert("Info", "No symbol maintained.",
					Configuration.ALERT_WAIT_TIME);
		}
		System.out.println(url);
	}

	public void setOverviewImage(Image img, int i) {
		imageArrayOverview[_type][i] = img;
		repaint();
	}

	private void calculateScreenSettings() {
		maxSlides = (_stocksVec.size() / stocksOnScreen);
		if ((_stocksVec.size() % stocksOnScreen) > 0)
			maxSlides++;
	}
}
